home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / typeface / source / fontio.c < prev    next >
C/C++ Source or Header  |  1996-05-11  |  19KB  |  677 lines

  1. /************************/
  2. /*            */
  3. /* Font loading, saving */
  4. /* and previewing.    */
  5. /*            */
  6. /************************/
  7.  
  8. #include "Typeface.h"
  9.  
  10. struct Window *PreviewWnd;
  11. struct ClipboardHandle *Clip, *Undo;
  12. Object *PreviewWndObj, *PreviewStr, *PreviewScroll;
  13. UBYTE *PreviewFont;
  14.  
  15. struct Window *QueryWnd;
  16. Object *QueryWndObj, *QueryWidthNum;
  17.  
  18. struct TextFont *tfh;
  19. struct NewMenu PreviewMenus[] = { PROJECT_MENU,FONT_MENU,PREVIEW_MENU,End };
  20.  
  21. extern struct Screen *Screen;
  22. extern struct MsgPort *WndMsgPort;
  23. extern struct Character CharBuffer[257];
  24. extern struct Window *SaveWnd;
  25. extern struct TextFont *NewFont;
  26. extern Object *SaveWndObj, *FontWndObj;
  27. extern ULONG FirstChar, LastChar;
  28. extern char WinTitle[256];
  29.  
  30. void OpenPreviewWnd(void)
  31. {
  32. Object *all, *cancel, *update, *clear;
  33.  
  34.   if (PreviewWnd)
  35.   {
  36.     WindowToFront(PreviewWnd);
  37.     ActivateWindow(PreviewWnd);
  38.     SetPreviewFont();
  39.     SetPreviewScroller();
  40.     ActivateGadget((struct Gadget *)PreviewStr,PreviewWnd,NULL);
  41.   }
  42.   else
  43.   {
  44.     if (PreviewWndObj == NULL)
  45.     {
  46.       Clip = OpenClipboard(PRIMARY_CLIP);
  47.       Undo = OpenClipboard(1);
  48.       SetupMenus(PreviewMenus);
  49.       PreviewWndObj = WindowObject,
  50.     WINDOW_Screen,Screen,
  51.     WINDOW_SharedPort,WndMsgPort,
  52.     WINDOW_MenuStrip,PreviewMenus,
  53.     WINDOW_Title,GetString(msgPreviewTitle),
  54.     WINDOW_HelpFile,NAME".guide",
  55.     WINDOW_HelpNode,"preview",
  56.     WINDOW_ScaleWidth,70,
  57.     WINDOW_ScaleHeight,70,
  58.     WINDOW_SmartRefresh,TRUE,
  59.     WINDOW_CloseOnEsc,TRUE,
  60.     WINDOW_MasterGroup,
  61.       VGroupObject,
  62.         HOffset(SizeX(8)),VOffset(SizeY(4)),Spacing(SizeY(4)),
  63.         GROUP_BackFill,SHINE_RASTER,
  64.         StartMember,
  65.           HGroupObject,
  66.         HOffset(SizeX(8)),VOffset(SizeY(4)),
  67.         ButtonFrame,
  68.         FRM_Recessed,TRUE,
  69.         StartMember,
  70.           PreviewStr = ExternalObject,
  71.             EXT_Class,TEXTFIELD_GetClass(),
  72.             EXT_NoRebuild,TRUE,
  73.             TEXTFIELD_BlockCursor,TRUE,
  74.             TEXTFIELD_Border,TEXTFIELD_BORDER_DOUBLEBEVEL,
  75.             TEXTFIELD_PassCommand,TRUE,
  76.             TEXTFIELD_NonPrintChars,TRUE,
  77.             TEXTFIELD_ClipStream,Clip,
  78.             TEXTFIELD_UndoStream,Undo,
  79.             GA_ID,ID_PREVIEWSTR,
  80.           EndObject,
  81.         EndMember,
  82.         StartMember,
  83.           PreviewScroll = VertScroller(NULL,0,0,0,ID_PREVIEWSCROLL),
  84.           FixMinWidth,
  85.         EndMember,
  86.           EndObject,
  87.         EndMember,
  88.         StartMember,
  89.           HGroupObject,
  90.         Spacing(SizeX(8)),
  91.         EqualWidth,
  92.         StartMember,
  93.           update = KeyButton(GetString(gadgUpdate),ID_UPDATE),
  94.         EndMember,
  95.         StartMember,
  96.           all = KeyButton(GetString(gadgShowAll),ID_ALL),
  97.         EndMember,
  98.             StartMember,
  99.           clear = KeyButton(GetString(gadgClear),ID_CLEAR),
  100.         EndMember,
  101.             StartMember,
  102.           cancel = KeyButton(GetString(gadgCancel),ID_CANCEL),
  103.         EndMember,
  104.           EndObject,
  105.           FixMinHeight,
  106.         EndMember,
  107.       EndObject,
  108.     EndObject;
  109.       if (PreviewWndObj == NULL) ErrorCode(NEWWINDOW);
  110.       SetLabelKey(PreviewWndObj,update,gadgUpdate);
  111.       SetLabelKey(PreviewWndObj,all,gadgShowAll);
  112.       SetLabelKey(PreviewWndObj,clear,gadgClear);
  113.       SetLabelKey(PreviewWndObj,cancel,gadgCancel);
  114.     }
  115.     SetPreviewFont();
  116.     if ((PreviewWnd = WindowOpen(PreviewWndObj)) == NULL)
  117.       ErrorCode(OPENWINDOW);
  118.     SetPreviewScroller();
  119.     ActivateGadget((struct Gadget *)PreviewStr,PreviewWnd,NULL);
  120.   }
  121. }
  122.  
  123. void ClosePreviewWnd(BOOL all)
  124. {
  125.   ClrWindowClose(&PreviewWndObj,&PreviewWnd);
  126.   if (all)
  127.   {
  128.     ClrDisposeObject(&PreviewWndObj);
  129.     if (Clip) { CloseClipboard(Clip); Clip = NULL; }
  130.     if (Undo) { CloseClipboard(Undo); Undo = NULL; }
  131.     if (PreviewFont) { FreeVec(PreviewFont); PreviewFont = NULL; }
  132.   }
  133. }
  134.  
  135. void SetPreviewFont()
  136. {
  137. ULONG fchar, lchar;
  138. UBYTE *oldfont;
  139.  
  140.   oldfont = PreviewFont;
  141.   fchar = FirstChar;
  142.   lchar = LastChar;
  143.   FirstChar = 0;
  144.   LastChar = 255;
  145.   PreviewFont = SaveFont(TRUE,TRUE);
  146.   FirstChar = fchar;
  147.   LastChar = lchar;
  148.   if (PreviewWnd)
  149.   {
  150.     SetGadgetAttrs((struct Gadget *)PreviewStr,PreviewWnd,NULL,
  151.       TEXTFIELD_TextFont,PreviewFont ? tfh : NULL,TAG_DONE);
  152.   }
  153.   else
  154.   {
  155.     SetAttrs(PreviewStr,
  156.       TEXTFIELD_TextFont,PreviewFont ? tfh : NULL,TAG_DONE);
  157.   }
  158.   if (oldfont) FreeVec(oldfont);
  159. }
  160.  
  161. void PreviewMsgs(ULONG code)
  162. {
  163. ULONG top;
  164.  
  165.   switch (code)
  166.   {
  167.     case ID_CLEAR:
  168.       SetGadgetAttrs((struct Gadget *)PreviewStr,PreviewWnd,NULL,
  169.     TEXTFIELD_Text,"",TAG_DONE);
  170.       ActivateGadget((struct Gadget *)PreviewStr,PreviewWnd,NULL);
  171.       break;
  172.     case ID_ALL:
  173.       PreviewAll();
  174.       break;
  175.     case ID_UPDATE:
  176.       SetPreviewFont();
  177.       break;
  178.     case ID_PREVIEWSCROLL:
  179.       GetAttr(PGA_Top,PreviewScroll,&top);
  180.       SetGadgetAttrs((struct Gadget *)PreviewStr,PreviewWnd,NULL,
  181.     TEXTFIELD_Top,top,TAG_DONE);
  182.       break;
  183.     case ID_PREVIEWSTR:
  184.       SetPreviewScroller();
  185.       break;
  186.     default:
  187.       SharedMsgs(code,NULL);
  188.       break;
  189.   }
  190. }
  191.  
  192. void SetPreviewScroller()
  193. {
  194. ULONG lines,visible,top;
  195.  
  196.   GetAttr(TEXTFIELD_Lines,PreviewStr,&lines);
  197.   GetAttr(TEXTFIELD_Visible,PreviewStr,&visible);
  198.   GetAttr(TEXTFIELD_Top,PreviewStr,&top);
  199.   SetGadgetAttrs((struct Gadget *)PreviewScroll,PreviewWnd,NULL,
  200.     PGA_Total,lines,
  201.     PGA_Visible,visible,
  202.     PGA_Top,top,TAG_DONE);
  203. }
  204.  
  205. #define PREVIEW_WIDTH 32
  206.  
  207. void PreviewAll(void)
  208. {
  209. int i,j;
  210. char listtext[((PREVIEW_WIDTH+1)*(256/PREVIEW_WIDTH))+1];
  211.  
  212.   for (i = 0; i < 256/PREVIEW_WIDTH; i++)
  213.   {
  214.     for (j = 0; j < PREVIEW_WIDTH; j++)
  215.     {
  216.       switch ((i*PREVIEW_WIDTH)+j)
  217.       {
  218.     case '\0':
  219.     case '\n':
  220.     case 0x0D:
  221.       listtext[(i*(PREVIEW_WIDTH+1))+j] = ' ';
  222.       break;
  223.     default:
  224.       listtext[(i*(PREVIEW_WIDTH+1))+j] = (i*PREVIEW_WIDTH)+j;
  225.       break;
  226.       }
  227.     }
  228.     listtext[(i*(PREVIEW_WIDTH+1))+PREVIEW_WIDTH] = '\n';
  229.   }
  230.   listtext[((PREVIEW_WIDTH+1)*(256/PREVIEW_WIDTH))] = '\0';
  231.   SetGadgetAttrs((struct Gadget *)PreviewStr,PreviewWnd,NULL,
  232.     TEXTFIELD_Text,listtext,TAG_DONE);
  233.   ActivateGadget((struct Gadget *)PreviewStr,PreviewWnd,NULL);
  234. }
  235.  
  236. UBYTE *SaveFont(BOOL tables,BOOL preview)
  237. {
  238. char fontpath[256], filename[256], datestr[LEN_DATSTRING];
  239. ULONG filesize = 0, numchars, bitwidth = 0, i, offbit, hunkstart;
  240. struct DateTime dt;
  241. struct DiskFontHeader *dfh;
  242. struct FontContentsHeader *fch;
  243. ULONG *longptr, *relocstart;
  244. UBYTE *buffer, *mptr, *fontdataptr;
  245. struct charDef *fontlocptr;
  246. WORD *fontkernptr;
  247. BPTR fontfile, contfile, lock;
  248.  
  249. extern ULONG Proportional, Normal, Bold, Italic, ULine, Extended, Reversed;
  250. extern ULONG Height, Width, Baseline, Smear, Aspect;
  251. extern WORD SpaceTable[257], KernTable[257];
  252. extern BOOL DataChanged;
  253. extern char SavePath[256], FontName[256];
  254.  
  255.   strcpy(fontpath,SavePath);
  256.   AddPart(fontpath,FontName,256);
  257.   sprintf(filename,"%s/%ld",fontpath,Height);
  258.  
  259.   DateStamp(&(dt.dat_Stamp));
  260.   dt.dat_Format = FORMAT_CDN;
  261.   dt.dat_Flags = 0;
  262.   dt.dat_StrDay = NULL;
  263.   dt.dat_StrDate = datestr;
  264.   dt.dat_StrTime = NULL;
  265.   DateToStr(&dt);
  266.   while ((mptr = strchr(datestr,'-')) != NULL) *mptr = '.';
  267.  
  268.   numchars = LastChar-FirstChar+2;
  269.   filesize += 14*4;            /* Hunk structure */
  270.   filesize += sizeof(struct DiskFontHeader);
  271.   filesize += 4*4;            /* Relocatable addresses */
  272.   for (i = FirstChar; i < LastChar+1; i++)
  273.     bitwidth += (CharBuffer+i)->chr_Width;
  274.   bitwidth += (CharBuffer+256)->chr_Width;
  275.   if (bitwidth % 16 > 0) bitwidth = ((bitwidth/16)+1)*16;
  276.   filesize += (bitwidth/8)*Height;    /* Character data */
  277.   filesize += numchars*sizeof(struct charDef);
  278.   if (tables)
  279.   {
  280.     filesize += numchars*4;        /* Space and kern tables */
  281.     filesize += 2*4;            /* Table relocs */
  282.   }
  283.   if (filesize % 4 > 0) filesize = ((filesize/4)+1)*4;
  284.   if ((buffer = AllocVec(filesize,MEMF_CLEAR)) != NULL)
  285.   {
  286.     longptr = (ULONG *)buffer;
  287.     *longptr++ = 0x000003F3;        /* Hunk structure */
  288.     *longptr++ = 0x00000000;
  289.     *longptr++ = 0x00000001;
  290.     *longptr++ = 0x00000000;
  291.     *longptr++ = 0x00000000;
  292.     *longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
  293.     *longptr++ = 0x000003E9;        /* Hunk size (twice) */
  294.     *longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
  295.     if (preview)
  296.       hunkstart = 0;
  297.     else
  298.       hunkstart = (ULONG)longptr;    /* All relocs relative to here */
  299.     *longptr++ = 0x70FF4E75;        /* MOVEQ #-1,D0 RTS */
  300.     relocstart = (ULONG *)(buffer+filesize-((9+(tables ? 2 : 0))*4));
  301.  
  302.     dfh = (struct DiskFontHeader *)longptr;
  303.     dfh->dfh_DF.ln_Type = NT_FONT;
  304.     dfh->dfh_DF.ln_Name = (UBYTE *)((ULONG)dfh->dfh_Name-hunkstart);
  305.     dfh->dfh_FileID = DFH_ID;
  306.     sprintf(dfh->dfh_Name,"$VER: %s%d 39.0 (%s)",FontName,Height,datestr);
  307.  
  308.     fontdataptr = ((UBYTE *)dfh)+sizeof(struct DiskFontHeader);
  309.     fontlocptr = (struct CharDef *)(fontdataptr+((bitwidth/8)*Height));
  310.     if ((ULONG)fontlocptr % 2 > 0)
  311.       fontlocptr = (struct charDef *)((((ULONG)fontlocptr/2)+1)*2);
  312.     fontkernptr = (WORD *)((UBYTE *)fontlocptr+
  313.       numchars*sizeof(struct charDef));
  314.  
  315.     tfh = &(dfh->dfh_TF);
  316.     tfh->tf_Message.mn_Node.ln_Type = NT_FONT;
  317.     tfh->tf_Message.mn_Node.ln_Name = dfh->dfh_DF.ln_Name;
  318.     tfh->tf_YSize = Height;
  319.     if (Normal == FALSE)
  320.     {
  321.       if (Bold) tfh->tf_Style |= FSF_BOLD;
  322.       if (Italic) tfh->tf_Style |= FSF_ITALIC;
  323.       if (ULine) tfh->tf_Style |= FSF_UNDERLINED;
  324.       if (Extended) tfh->tf_Style |= FSF_EXTENDED;
  325.     }
  326.     else tfh->tf_Style = FS_NORMAL;
  327.     tfh->tf_Flags = FPF_DESIGNED|FPF_DISKFONT;
  328.     if (Proportional) tfh->tf_Flags |= FPF_PROPORTIONAL;
  329.     if (Reversed) tfh->tf_Flags |= FPF_REVPATH;
  330.     switch (Aspect)
  331.     {
  332.       case 1:
  333.     tfh->tf_Flags |= FPF_TALLDOT;
  334.     break;
  335.       case 2:
  336.     tfh->tf_Flags |= FPF_WIDEDOT;
  337.     break;
  338.     }
  339.     tfh->tf_XSize = Width;
  340.     tfh->tf_Baseline = Baseline;
  341.     tfh->tf_BoldSmear = Smear;
  342.     tfh->tf_LoChar = FirstChar;
  343.     tfh->tf_HiChar = LastChar;
  344.     tfh->tf_CharData = (UBYTE *)((ULONG)fontdataptr-hunkstart);
  345.     tfh->tf_Modulo = bitwidth/8;
  346.     tfh->tf_CharLoc = (UBYTE *)((ULONG)fontlocptr-hunkstart);
  347.     if (tables)
  348.     {
  349.       tfh->tf_CharSpace = (UBYTE *)((ULONG)fontkernptr-hunkstart);
  350.       tfh->tf_CharKern =
  351.     (UBYTE *)((ULONG)fontkernptr+(numchars*2)-hunkstart);
  352.     }
  353.     for (i = FirstChar, offbit = 0; i < LastChar+1; i++)
  354.     {
  355.       WriteCharData(fontlocptr,fontdataptr,i-FirstChar,i,&offbit,bitwidth/8);
  356.       if (tables)
  357.       {
  358.     *(fontkernptr+(i-FirstChar)) = SpaceTable[i];
  359.     *(fontkernptr+(i-FirstChar+numchars)) = KernTable[i];
  360.       }
  361.     }
  362.     WriteCharData(fontlocptr,fontdataptr,numchars-1,256,&offbit,bitwidth/8);
  363.     if (tables)
  364.     {
  365.       *(fontkernptr+(numchars-1)) = SpaceTable[256];
  366.       *(fontkernptr+(numchars-1+numchars)) = KernTable[256];
  367.     }
  368.  
  369.     *relocstart++ = 0x000003EC;        /* Reloc structure */
  370.     *relocstart++ = 4 + (tables ? 2 : 0);
  371.     *relocstart++ = 0x00000000;
  372.     if (tables)
  373.     {
  374.       *relocstart++ = (ULONG)(&(tfh->tf_CharKern))-hunkstart;
  375.       *relocstart++ = (ULONG)(&(tfh->tf_CharSpace))-hunkstart;
  376.     }
  377.     *relocstart++ = (ULONG)(&(tfh->tf_CharLoc))-hunkstart;
  378.     *relocstart++ = (ULONG)(&(tfh->tf_CharData))-hunkstart;
  379.     *relocstart++ = (ULONG)(&(tfh->tf_Message.mn_Node.ln_Name))-hunkstart;
  380.     *relocstart++ = (ULONG)(&(dfh->dfh_DF.ln_Name))-hunkstart;
  381.     *relocstart++ = 0x00000000;
  382.     *relocstart++ = 0x000003F2;
  383.  
  384.     if (preview) return (buffer);
  385.  
  386.     WindowBusy(SaveWndObj);
  387.     lock = Lock(fontpath,ACCESS_READ);
  388.     WindowReady(SaveWndObj);
  389.     if (lock == 0)
  390.     {
  391.       if (SaveShowReq(GetString(msgSaveNoDir),GetString(msgSaveNoDirGadgets),
  392.     fontpath))
  393.       {
  394.         WindowBusy(SaveWndObj);
  395.         lock = CreateDir(fontpath);
  396.         WindowReady(SaveWndObj);
  397.     if (lock == 0)
  398.     {
  399.       SaveShowReq(GetString(msgSaveCreateError),GetString(msgCancel),
  400.         fontpath);
  401.       if (buffer) FreeVec(buffer);
  402.       return;
  403.     }
  404.     else UnLock(lock);
  405.       }
  406.       else
  407.       {
  408.     if (buffer) FreeVec(buffer);
  409.     return;
  410.       }
  411.     }
  412.     else UnLock(lock);
  413.  
  414.     WindowBusy(SaveWndObj);
  415.     lock = Lock(filename,ACCESS_READ);
  416.     WindowReady(SaveWndObj);
  417.     if (lock)
  418.     {
  419.       UnLock(lock);
  420.       if (!SaveShowReq(GetString(msgSaveWarnExists),
  421.     GetString(msgSaveWarnExistsGadgets),filename))
  422.       {
  423.     if (buffer) FreeVec(buffer);
  424.     return;
  425.       }
  426.     }
  427.  
  428.     WindowBusy(SaveWndObj);
  429.     fontfile = Open(filename,MODE_NEWFILE);
  430.     WindowReady(SaveWndObj);
  431.     if (fontfile)
  432.     {
  433.       WindowBusy(SaveWndObj);
  434.       Write(fontfile,buffer,filesize);
  435.       Close(fontfile);
  436.       DataChanged = FALSE;
  437.  
  438.       lock = Lock(SavePath,ACCESS_READ);
  439.       WindowReady(SaveWndObj);
  440.       if (lock != 0)
  441.       {
  442.     sprintf(filename,"%s.font",fontpath);
  443.     WindowBusy(SaveWndObj);
  444.     fch = NewFontContents(lock,FilePart(filename));
  445.     WindowReady(SaveWndObj);
  446.     if (fch != NULL)
  447.     {
  448.       WindowBusy(SaveWndObj);
  449.       contfile = Open(filename,MODE_NEWFILE);
  450.       WindowReady(SaveWndObj);
  451.       if (contfile != 0)
  452.       {
  453.         WindowBusy(SaveWndObj);
  454.         Write(contfile,fch,sizeof(struct FontContentsHeader)+
  455.           (fch->fch_NumEntries*sizeof(struct FontContents)));
  456.         Close(contfile);
  457.         WindowReady(SaveWndObj);
  458.       }
  459.       else SaveShowReq(GetString(msgSaveWriteHeader),
  460.         GetString(msgCancel),filename);
  461.       DisposeFontContents(fch);
  462.     }
  463.     else ShowReq(GetString(msgSaveCreateHeader),GetString(msgCancel));
  464.     UnLock(lock);
  465.       }
  466.     }
  467.     else SaveShowReq(GetString(msgSaveWriteData),GetString(msgCancel),
  468.       filename);
  469.   }
  470.   else SaveShowReq(GetString(msgSaveNoMemory),GetString(msgCancel));
  471.   if (buffer) FreeVec(buffer);
  472.   FlushAllFonts();
  473.   return (NULL);
  474. }
  475.  
  476. ULONG SaveShowReq(char *text,char *gadgets,...)
  477. {
  478. va_list va;
  479. struct EasyStruct req =
  480.   { sizeof(struct EasyStruct),0,NAME,NULL,NULL };
  481. ULONG retcode;
  482.  
  483.   if (SaveWnd == NULL) return (0);
  484.   WindowBusy(SaveWndObj);
  485.   req.es_TextFormat = text;
  486.   req.es_GadgetFormat = gadgets;
  487.   va_start(va,gadgets);
  488.   retcode = EasyRequestArgs(SaveWnd,&req,NULL,va);
  489.   va_end(va);
  490.   WindowReady(SaveWndObj);
  491.   return (retcode);
  492. }
  493.  
  494. void WriteCharData(struct charDef *cd, UBYTE *fontdataptr, ULONG dest,
  495.   ULONG src, ULONG *off, ULONG mod)
  496. {
  497. struct Character *chr;
  498. UBYTE *data;
  499. ULONG i,j,width,widthi,modi,offset;
  500.  
  501.   chr = CharBuffer+src;
  502.   data = (chr->chr_Data == NULL) ?
  503.     (CharBuffer+256)->chr_Data : chr->chr_Data;
  504.   width = chr->chr_Width;
  505.   offset = *off;
  506.   for (i = 0; i < chr->chr_Height; i++)
  507.   {
  508.     modi = mod*i;
  509.     widthi = width*i;
  510.     for (j = 0; j < width; j++)
  511.     {
  512.       if (*(data+widthi+j) == 1)
  513.     *(fontdataptr+modi+((offset+j)>>3)) |= 128>>((offset+j)&7);
  514.     }
  515.   }
  516.   (cd+dest)->charOffset = offset;
  517.   (cd+dest)->charBitWidth = width;
  518.   *off += width;
  519. }
  520.  
  521. void OpenQueryWidthWnd(void)
  522. {
  523. Object *load, *info;
  524. ULONG args[2];
  525. extern char FontName[256];
  526. extern ULONG Height;
  527.  
  528.   if (QueryWndObj == NULL)
  529.   {
  530.     QueryWndObj = WindowObject,
  531.       WINDOW_Screen,Screen,
  532.       WINDOW_SharedPort,WndMsgPort,
  533.       WINDOW_Title,GetString(msgQueryWidthTitle),
  534.       WINDOW_HelpFile,NAME".guide",
  535.       WINDOW_HelpNode,"open",
  536.       WINDOW_ScaleWidth,10,
  537.       WINDOW_SmartRefresh,TRUE,
  538.       WINDOW_SizeGadget,FALSE,
  539.       WINDOW_CloseGadget,FALSE,
  540.       WINDOW_RMBTrap,TRUE,
  541.       WINDOW_MasterGroup,
  542.     VGroupObject,
  543.       HOffset(SizeX(8)),VOffset(SizeY(4)),Spacing(SizeY(4)),
  544.       GROUP_BackFill,SHINE_RASTER,
  545.       StartMember,
  546.         VGroupObject,
  547.           HOffset(SizeX(8)),VOffset(SizeY(4)),Spacing(SizeY(2)),
  548.           ButtonFrame,
  549.           FRM_Recessed,TRUE,
  550.           StartMember,
  551.         HGroupObject,
  552.           Spacing(SizeX(8)),
  553.           StartMember,
  554.             info = InfoObject,
  555.               ButtonFrame,
  556.               FRM_Flags,FRF_RECESSED,
  557.               Label(GetString(msgQueryFont)),
  558.               INFO_TextFormat,"%s/%ld",
  559.               INFO_Args,args,
  560.               INFO_MinLines,1,
  561.               INFO_HorizOffset,6,
  562.               INFO_VertOffset,3,
  563.               INFO_FixTextWidth,TRUE,
  564.             EndObject,
  565.           EndMember,
  566.           StartMember,
  567.             QueryWidthNum = StringObject,
  568.               RidgeFrame,
  569.               UScoreLabel(GetString(gadgQueryNewWidth),'_'),
  570.               STRINGA_LongVal,Width,
  571.               STRINGA_IntegerMin,0,
  572.               STRINGA_IntegerMax,65535,
  573.               STRINGA_MaxChars,5,
  574.               STRINGA_MinCharsVisible,4,
  575.               GA_ID,ID_QUERYWIDTHNUM,
  576.             EndObject,
  577.             Weight(40),
  578.           EndMember,
  579.         EndObject,
  580.           EndMember,
  581.         EndObject,
  582.       EndMember,
  583.       StartMember,
  584.         load = KeyButton(GetString(gadgLoad),ID_ACCEPT),
  585.         FixMinHeight,
  586.       EndMember,
  587.     EndObject,
  588.       EndObject;
  589.     if (QueryWndObj == NULL) ErrorCode(NEWWINDOW);
  590.     SetLabelKey(QueryWndObj,QueryWidthNum,gadgQueryNewWidth);
  591.     SetLabelKey(QueryWndObj,load,gadgLoad);
  592.     SetAttrs(QueryWidthNum,STRINGA_BufferPos,1);
  593.     if (Width > 10) SetAttrs(QueryWidthNum,STRINGA_BufferPos,2);
  594.     if (Width > 100) SetAttrs(QueryWidthNum,STRINGA_BufferPos,3);
  595.   }
  596.   args[0] = (ULONG)FontName;
  597.   args[1] = Height;
  598.   if ((QueryWnd = WindowOpen(QueryWndObj)) == NULL) ErrorCode(OPENWINDOW);
  599.   ActivateGadget((struct Gadget *)QueryWidthNum,QueryWnd,NULL);
  600. }
  601.  
  602. void CloseQueryWidthWnd(void)
  603. {
  604.   ClrWindowClose(&QueryWndObj,&QueryWnd);
  605.   ClrDisposeObject(&QueryWndObj);
  606. }
  607.  
  608. BOOL LoadFont(struct TextAttr *font, ULONG width)
  609. {
  610. ULONG i;
  611. char *endptr;
  612. struct TTextAttr tagfont;
  613. ULONG tags[3];
  614.  
  615.   strcpy(FontName,font->ta_Name);
  616.   if (endptr = strstr(FontName,".font")) *endptr = 0;
  617.  
  618.   if (width > 0)
  619.   {
  620.     CopyMem(font,&tagfont,sizeof(struct TextAttr));
  621.     tagfont.tta_Flags &= ~FPF_DESIGNED;
  622.     tagfont.tta_Style |= FSF_TAGGED;
  623.     tagfont.tta_Tags = (struct TagItem *)tags;
  624.     tags[0] = TA_DeviceDPI;
  625.     tags[1] = (width<<16)+tagfont.tta_YSize;
  626.     tags[2] = TAG_DONE;
  627.     NewFont = OpenDiskFont((struct TextAttr *)&tagfont);
  628.   }
  629.   else NewFont = OpenDiskFont(font);
  630.  
  631.   if (NewFont == NULL)
  632.   {
  633.     ShowReq(GetString(msgNoOpenFont),GetString(msgContinue),FontName,
  634.       (ULONG)font->ta_YSize);
  635.     return FALSE;
  636.   }
  637.   ClearCurrentFont();
  638.   Height = NewFont->tf_YSize;
  639.   Width = NewFont->tf_XSize;
  640.   Baseline = NewFont->tf_Baseline;
  641.   Smear = NewFont->tf_BoldSmear;
  642.   FirstChar = NewFont->tf_LoChar;
  643.   LastChar = NewFont->tf_HiChar;
  644.   Proportional = ((NewFont->tf_Flags & FPF_PROPORTIONAL) != 0);
  645.   Bold = ((NewFont->tf_Style & FSF_BOLD) != 0);
  646.   Italic = ((NewFont->tf_Style & FSF_ITALIC) != 0);
  647.   ULine = ((NewFont->tf_Style & FSF_UNDERLINED) != 0);
  648.   Extended = ((NewFont->tf_Style & FSF_EXTENDED) != 0);
  649.   Normal = ((Bold | Italic | ULine | Extended) == 0);
  650.   Reversed = ((NewFont->tf_Flags & FPF_REVPATH) != 0);
  651.   Aspect = 0;
  652.   if (NewFont->tf_Flags & FPF_TALLDOT) Aspect = 1;
  653.   if (NewFont->tf_Flags & FPF_WIDEDOT) Aspect = 2;
  654.  
  655.   for (i = 0; i < 257; i++)
  656.   {
  657.     (CharBuffer+i)->chr_Width = (((struct charDef *)(NewFont->tf_CharLoc))
  658.       +LastChar-FirstChar+1)->charBitWidth;
  659.     (CharBuffer+i)->chr_Height = NewFont->tf_YSize;
  660.     SpaceTable[i] = NewFont->tf_XSize;
  661.     KernTable[i] = 0;
  662.     KernTables(i,LastChar-FirstChar+1);
  663.   }
  664.   for (i = 0; i < LastChar-FirstChar+1; i++)
  665.   {
  666.     if (!UnpackChar(CharBuffer+FirstChar+i,NewFont,i)) ErrorCode(ALLOCVEC);
  667.     KernTables(FirstChar+i,i);
  668.   }
  669.   UnpackChar(CharBuffer+256,NewFont,LastChar-FirstChar+1);
  670.   KernTables(256,LastChar-FirstChar+1);
  671.   sprintf(WinTitle,"%s/%ld",FontName,(ULONG)font->ta_YSize);
  672.   SetAttrs(FontWndObj,WINDOW_Title,WinTitle,TAG_DONE);
  673.   CloseFont(NewFont); NewFont = NULL;
  674.   DataChanged = FALSE;
  675.   return TRUE;
  676. }
  677.